home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Peter Lewis / PNL Libraries / MyListWindow.p < prev    next >
Encoding:
Text File  |  1994-09-14  |  17.7 KB  |  722 lines  |  [TEXT/PJMM]

  1. unit MyListWindow;
  2.  
  3. interface
  4.  
  5.     uses
  6.         MyOOMainLoop;
  7.  
  8.     type
  9.         ListWindowObject = object(DObject)
  10.                 list: ListHandle;
  11.                 hcontrol: ControlHandle;
  12.                 list_offset, list_width, max_display_width, header_height: integer;
  13.                 typed_chars: str31;
  14.                 typed_time: longInt;
  15.                 procedure CreateList (font, size: integer; ldefID: integer; hscroll: boolean);
  16.                 procedure Destroy;
  17.                 override;
  18.                 procedure DoItemWhere (er: eventRecord; item: integer);
  19.                 override;
  20.                 procedure Resize;
  21.                 override;
  22.                 procedure DrawGrow;
  23.                 override;
  24.                 procedure DoActivateDeactivate (activate: boolean);
  25.                 override;
  26.                 procedure DoKey (modifiers: integer; ch: char; code: integer);
  27.                 override;
  28.                 procedure SelectAll (on: boolean);
  29.                 function Match (c: cell; var what: str255): boolean;
  30.                 procedure Find (what: str255; fromstart, allatonce: boolean);
  31.                 procedure AdjustHContol (canRedraw: BOOLEAN);
  32.                 procedure SetListWidth (max: integer);
  33.                 function DontDrag (er: EventRecord): boolean;
  34.                 function DoLClick (er: EventRecord): boolean;
  35.                 procedure DoDoubleClick;
  36.                 procedure DoDoubleClickCell (c: cell);
  37.                 function GetEntryName (c: cell): str255;
  38.                 function GetUniqueEntryName (c: cell): str255;
  39.                 procedure OpenParent;
  40.                 procedure LDEF (message: integer; select: boolean; var r: Rect; c: Cell; dataOffset, dataLen: integer);
  41.                 procedure DrawHeader (r: rect);
  42.                 procedure DoHeaderClick (r: rect; where: Point; modifiers: integer);
  43.                 procedure SetSingleSelection (v: integer);
  44.                 function SelectFirstAfter (s: str255): boolean;
  45.                 function SelectFirstBefore (s: str255): boolean;
  46.                 function GetFirstSelection (var c: Cell): boolean;
  47.                 function GetLastSelection (var c: Cell): boolean;
  48.                 function CountSelections: integer;
  49.                 function IsSelection: boolean;
  50.                 function DoSetupDragCell (c: cell; dragref: DragReference; dragrgn: RgnHandle): OSErr;
  51.                 function DoSetupDrag (dragref: DragReference; dragrgn: RgnHandle): OSErr;
  52.                 override;
  53.             end;
  54.  
  55. implementation
  56.  
  57.     uses
  58.         MyDialogs, MyAssertions, MyTypes, MyMathUtils, Drag, MyListManager;
  59.  
  60.     const
  61.         list_item = 1;
  62.  
  63.     procedure DrawList (dp: dialogPtr; item: integer);
  64.         var
  65.             r, rh: rect;
  66.             obj: ListWindowObject;
  67.     begin
  68.         SetPort(dp);
  69.         obj := ListWindowObject(GetWObject(dp));
  70.         PenNormal;
  71.         GetDItemRect(dp, item, r);
  72.         rh := r;
  73.         r.top := r.top + obj.header_height + 1;
  74.         InsetRect(r, -1, -1);
  75.         FrameRect(r);
  76.         if obj.header_height > 0 then begin
  77.             rh.bottom := rh.top + obj.header_height;
  78.             obj.DrawHeader(rh);
  79.         end;
  80.         obj.DrawGrow;
  81.         LUpdate(dp^.visRgn, obj.list);
  82.     end;
  83.  
  84.     procedure ListWindowObject.SelectAll (on: boolean);
  85.         var
  86.             i: integer;
  87.             c: cell;
  88.     begin
  89.         for i := 0 to list^^.databounds.bottom - 1 do begin
  90.             c.h := 0;
  91.             c.v := i;
  92.             LSetSelect(on, c, list);
  93.         end;
  94.     end;
  95.  
  96.     function ListWindowObject.Match (c: cell; var what: str255): boolean;
  97.     begin
  98.         Match := false;
  99.     end;
  100.  
  101.     procedure ListWindowObject.Find (what: str255; fromstart, allatonce: boolean);
  102.         var
  103.             from: integer;
  104.             c: cell;
  105.             found, found1: boolean;
  106.     begin
  107.         if allatonce then begin
  108.             found := false;
  109.             c.h := 0;
  110.             while (c.v < list^^.databounds.bottom) do begin
  111.                 found1 := Match(c, what);
  112.                 LSetSelect(found1, c, list);
  113.                 if found1 then begin
  114.                     found := true;
  115.                 end;
  116.                 c.v := c.v + 1;
  117.             end;
  118.         end
  119.         else begin
  120.             c.v := 0;
  121.             c.h := 0;
  122.             if not fromstart then begin
  123.                 while LGetSelect(true, c, list) do begin
  124.                     c.v := c.v + 1;
  125.                     c.h := 0;
  126.                 end;
  127.             end;
  128.             found := false;
  129.             while (c.v < list^^.databounds.bottom) do begin
  130.                 found := Match(c, what);
  131.                 if found then begin
  132.                     leave;
  133.                 end;
  134.                 c.v := c.v + 1;
  135.             end;
  136.             if found then begin
  137.                 SetSingleSelection(c.v);
  138.             end;
  139.         end;
  140.         if not found then begin
  141.             SysBeep(1);
  142.         end;
  143.     end;
  144.  
  145.     procedure ListWindowObject.LDEF (message: integer; select: boolean; var r: Rect; c: Cell; dataOffset, dataLen: integer);
  146.     begin
  147.     end;
  148.  
  149.     procedure ListWindowObject.DrawHeader (r: rect);
  150.     begin
  151.     end;
  152.  
  153.     procedure ListWindowObject.DoHeaderClick (r: rect; where: Point; modifiers: integer);
  154.     begin
  155.     end;
  156.  
  157.     procedure CallLDEF (message: integer; select: boolean; var r: Rect; c: Cell; dataOffset, dataLen: integer; lh: ListHandle);
  158.     begin
  159.         ListWindowObject(GetWObject(lh^^.port)).LDEF(message, select, r, c, dataOffset, dataLen);
  160.     end;
  161.  
  162.     procedure ListWindowObject.SetListWidth (max: integer);
  163.     begin
  164.         list_width := max;
  165.         zoomSize.h := max + 16;
  166.         zoomSize.v := list^^.cellSize.v * (list^^.dataBounds.bottom + 1) + 2;
  167.         AdjustHContol(true);
  168.     end;
  169.  
  170.     procedure ListWindowObject.AdjustHContol (canRedraw: BOOLEAN);
  171. {Calculate the new control maximum value and current value }
  172. {max is calculated by comparing the maximum document}
  173. {width to the width of the viewRect. The current values are set by comparing the offset between}
  174. {the view and destination rects. If necessary and we canRedraw, have the control be re-drawn by}
  175. {calling ShowControl.}
  176.         var
  177.             value, lines, max: INTEGER;
  178.             oldValue, oldMax: INTEGER;
  179.             cliprgn: RgnHandle;
  180.             r: rect;
  181.     begin
  182.         oldValue := GetCtlValue(hcontrol);
  183.         oldMax := GetCtlMax(hcontrol);
  184.         GetDItemRect(window, list_item, r);
  185.         max := list_width - (r.right - 16 - r.left);
  186.         if max < 0 then
  187.             max := 0;            {check for negative values}
  188.         list_offset := Pin(0, list_offset, max);
  189.         SetPort(window);
  190.         clipRgn := NewRgn;
  191.         GetClip(clipRgn);
  192.         SetRect(r, 0, 0, 0, 0);
  193.         ClipRect(r);
  194.         SetCtlMax(hcontrol, max);
  195.         SetClip(clipRgn);
  196.         DisposeRgn(clipRgn);
  197.         SetCtlValue(hcontrol, list_offset);
  198.         if canRedraw and ((max <> oldMax) or (value <> oldValue)) then
  199.             ShowControl(hcontrol);            {check to see if the control can be re-drawn}
  200.     end; {AdjustHContol}
  201.  
  202.     procedure ListWindowObject.CreateList (font, size: integer; ldefID: integer; hscroll: boolean);
  203.         var
  204.             view, bounds: rect;
  205.             siz: point;
  206.             k: integer;
  207.             h: handle;
  208.             oldrefcon: longInt;
  209.             fi: FontInfo;
  210.             dr: rect;
  211.     begin
  212.         handle_shift_tab := false;
  213.         typed_time := 0;
  214.         max_display_width := maxInt;
  215.         header_height := 0;
  216.         SetPort(window);
  217.         TextFont(font);
  218.         TextSize(size);
  219.         GetFontInfo(fi);
  220.         draw_grow_icon := true;
  221.         GetDItem(window, list_item, k, h, view);
  222.         SetDItem(window, list_item, k, handle(@DrawList), view);
  223.         SetRect(bounds, 0, 0, 1, 0);
  224.         view.right := view.right - 15;
  225.         SetPt(siz, 30000, fi.ascent + fi.descent + fi.leading);
  226.         list := LNew(view, bounds, siz, ldefID, window, true, true, false, true);
  227.         list^^.refcon := longInt(@CallLDEF);
  228.         if hscroll then begin
  229.             SetRect(dr, 0, 0, 100, 16);
  230.             hcontrol := NewControl(window, dr, '', true, 0, 0, 0, scrollBarProc, 0);
  231.         end
  232.         else begin
  233.             hcontrol := nil;
  234.         end;
  235.         Resize;
  236.     end;
  237.  
  238.     procedure ListWindowObject.Destroy;
  239.     begin
  240.         LDispose(list);
  241.         inherited Destroy;
  242.     end;
  243.  
  244.     procedure ListWindowObject.DoDoubleClickCell (c: cell);
  245.     begin
  246.     end;
  247.  
  248.     function ListWindowObject.DoSetupDragCell (c: cell; dragref: DragReference; dragrgn: RgnHandle): OSErr;
  249.     begin
  250.         DoSetupDragCell := -1;
  251.     end;
  252.  
  253.     function ListWindowObject.DoSetupDrag (dragref: DragReference; dragrgn: RgnHandle): OSErr;
  254.         var
  255.             c: Cell;
  256.             err: OSErr;
  257.     begin
  258.         err := -23;
  259.         c.h := 0;
  260.         c.v := 0;
  261.         while LGetSelect(true, c, list) do begin
  262.             err := DoSetupDragCell(c, dragref, dragrgn);
  263.             if err <> noErr then
  264.                 leave;
  265.             c.v := c.v + 1;
  266.             c.h := 0;
  267.         end;
  268.         DoSetupDrag := err;
  269.     end;
  270.  
  271.     var
  272.         CLFirstCall: boolean;
  273.         CLFirstPt: Point;
  274.         CLlist: ListHandle;
  275.         CLer: EventRecord;
  276.         CLwobj: WObject;
  277.  
  278.     function MyClickLoop2: boolean;
  279.         var
  280.             r, cellRect: rect;
  281.             cellClicked: Cell;
  282.             curPt: Point;
  283.             dummy: boolean;
  284.             ret: boolean;
  285.     begin
  286.         ret := true;
  287.         if CLFirstCall then begin
  288.             CLFirstCall := false;
  289.             GetMouse(CLFirstPt);
  290.         end
  291.         else begin
  292.             SetRect(r, CLfirstPt.h - 3, CLfirstPt.v - 3, CLfirstPt.h + 3, CLfirstPt.v + 3);
  293.             cellClicked := LLastClick(CLlist);
  294.             LRect(cellRect, cellClicked, CLlist);
  295.             dummy := SectRect(r, cellRect, r);
  296.             GetMouse(curPt);
  297.             if not PtInRect(curPt, r) then begin
  298.                 CLwobj.DoTrackDrag(CLer);
  299.                 ret := false;
  300.             end;
  301.         end;
  302.         MyClickLoop2 := ret;
  303.     end;
  304.  
  305. {$PUSH}
  306. {$D-}
  307.     function MyClickLoop: boolean; { returns the bloody equal flag for gods sake! }
  308.     begin
  309.         MyClickLoop := MyClickLoop2; { BE VERY CAREFUL!  Returns the equal flag! }
  310.     end;
  311. {$POP}
  312.  
  313.     function ListWindowObject.DontDrag (er: EventRecord): boolean;
  314.     begin
  315.         DontDrag := last_event_had_shift or last_event_had_command;
  316.     end;
  317.  
  318.     function ListWindowObject.DoLClick (er: EventRecord): boolean;
  319.         var
  320.             double: boolean;
  321.             savedcl: ProcPtr;
  322.             local: Point;
  323.     begin
  324.         local := er.where;
  325.         GlobalToLocal(local);
  326.         if not has_DragManager or DontDrag(er) then begin
  327.             double := LClick(local, er.modifiers, list);
  328.         end
  329.         else begin
  330.             savedcl := list^^.lClikLoop;
  331.             list^^.lClikLoop := @MyClickLoop;
  332.             CLFirstCall := true;
  333.             CLlist := list;
  334.             CLer := er;
  335.             CLwobj := self;
  336.             double := LClick(local, er.modifiers, list);
  337.             list^^.lClikLoop := savedcl;
  338.         end;
  339.         DoLClick := double;
  340.     end;
  341.  
  342.     procedure ListWindowObject.OpenParent;
  343.     begin
  344.     end;
  345.  
  346.     procedure ListWindowObject.SetSingleSelection (v: integer);
  347.     begin
  348.         LSetSingleSelection(list, v);
  349.         LAutoScroll(list);
  350.     end;
  351.  
  352.     procedure ListWindowObject.DoDoubleClick;
  353.         var
  354.             c: Cell;
  355.     begin
  356.         c.h := 0;
  357.         c.v := 0;
  358.         while LGetSelect(true, c, list) do begin
  359.             DoDoubleClickCell(c);
  360.             c.v := c.v + 1;
  361.             c.h := 0;
  362.         end;
  363.     end;
  364.  
  365.     var
  366.         action_listobj: ListWindowObject;
  367.  
  368.     procedure CommonAction (control: ControlHandle; var amount: integer);
  369.         var
  370.             value, max, ovalue: integer;
  371.     begin
  372.         value := GetCtlValue(control);
  373.         ovalue := value;
  374.         max := GetCtlMax(control);
  375.         value := Pin(0, value - amount, max);
  376.         if value <> ovalue then begin
  377.             SetCtlValue(control, value);
  378.         end;
  379.         amount := ovalue - value;   { calculate true change }
  380.     end; { CommonAction  }
  381.  
  382. { Determines how much to change the value of the horizontal scrollbar by and how }
  383. { much to scroll the TE record. }
  384.     procedure HActionProc (control: ControlHandle; part: integer);
  385.         var
  386.             amount: integer;
  387.             window: WindowPtr;
  388.     begin
  389.         if (part <> 0) then begin
  390.             window := action_listobj.window;
  391.             case part of
  392.                 inUpButton, inDownButton:        { a few pixels }
  393.                     amount := 8;
  394.                 inPageUp, inPageDown:            { a page width }
  395.                     with action_listobj.list^^.rView do
  396.                         amount := (right - left);
  397.             end;
  398.             if ((part = inDownButton) or (part = inPageDown)) then
  399.                 amount := -amount;        { reverse direction }
  400.             CommonAction(control, amount);
  401.             if amount <> 0 then begin
  402.                 action_listobj.list_offset := GetCtlValue(control);
  403.                 DrawList(window, list_item);
  404.             end;
  405.         end;
  406.     end; { HActionProc }
  407.  
  408.     function ListWindowObject.GetEntryName (c: cell): str255;
  409.     begin
  410.         GetEntryName := '';
  411.     end;
  412.  
  413.     function ListWindowObject.GetUniqueEntryName (c: cell): str255;
  414.     begin
  415.         GetUniqueEntryName := concat(GetEntryName(c), chr(0), chr(c.v div 256), chr(c.v mod 256));
  416.     end;
  417.  
  418.     function ListWindowObject.SelectFirstAfter (s: str255): boolean;
  419.         var
  420.             i, index: integer;
  421.             c: Cell;
  422.             best, n: str255;
  423.             good: boolean;
  424.     begin
  425.         good := false;
  426.         best := concat(chr(255), chr(255));
  427.         for i := 0 to list^^.databounds.bottom - 1 do begin
  428.             c.h := 0;
  429.             c.v := i;
  430.             n := GetUniqueEntryName(c);
  431.             if (IUCompString(s, n) < 0) & (IUCompString(n, best) < 0) then begin
  432.                 best := n;
  433.                 index := c.v;
  434.                 good := true;
  435.             end;
  436.         end;
  437.         if good then begin
  438.             SetSingleSelection(index);
  439.         end;
  440.         SelectFirstAfter := good;
  441.     end;
  442.  
  443.     function ListWindowObject.SelectFirstBefore (s: str255): boolean;
  444.         var
  445.             i, index: integer;
  446.             c: Cell;
  447.             best, n: str255;
  448.             good: boolean;
  449.     begin
  450.         good := false;
  451.         index := 0;
  452.         best := '';
  453.         for i := 0 to list^^.databounds.bottom - 1 do begin
  454.             c.h := 0;
  455.             c.v := i;
  456.             n := GetUniqueEntryName(c);
  457.             if (IUCompString(s, n) > 0) & (IUCompString(n, best) > 0) then begin
  458.                 best := n;
  459.                 index := c.v;
  460.                 good := true;
  461.             end;
  462.         end;
  463.         if good then begin
  464.             SetSingleSelection(index);
  465.         end;
  466.         SelectFirstBefore := good;
  467.     end;
  468.  
  469.     function ListWindowObject.GetFirstSelection (var c: Cell): boolean;
  470.         var
  471.             best, n: str255;
  472.             index: integer;
  473.     begin
  474.         GetFirstSelection := false;
  475.         c.h := 0;
  476.         c.v := 0;
  477.         best := concat(chr(255), chr(255));
  478.         while LGetSelect(true, c, list) do begin
  479.             GetFirstSelection := true;
  480.             n := GetUniqueEntryName(c);
  481.             if IUCompString(n, best) < 0 then begin
  482.                 index := c.v;
  483.             end;
  484.             c.v := c.v + 1;
  485.         end;
  486.         c.h := 0;
  487.         c.v := index;
  488.     end;
  489.  
  490.     function ListWindowObject.GetLastSelection (var c: Cell): boolean;
  491.         var
  492.             best, n: str255;
  493.             index: integer;
  494.     begin
  495.         GetLastSelection := false;
  496.         c.h := 0;
  497.         c.v := 0;
  498.         best := '';
  499.         while LGetSelect(true, c, list) do begin
  500.             GetLastSelection := true;
  501.             n := GetUniqueEntryName(c);
  502.             if IUCompString(n, best) > 0 then begin
  503.                 index := c.v;
  504.             end;
  505.             c.v := c.v + 1;
  506.         end;
  507.         c.h := 0;
  508.         c.v := index;
  509.     end;
  510.  
  511.     procedure ListWindowObject.DoKey (modifiers: integer; ch: char; code: integer);
  512.         var
  513.             c: Cell;
  514.             index: integer;
  515.             dummy: boolean;
  516.     begin
  517.         if ch < ' ' then begin
  518.             typed_time := 0;
  519.         end;
  520.         case ord(ch) of
  521.             downArrowChar:  begin
  522.                 if last_event_had_command then begin
  523.                     DoDoubleClick;
  524.                 end
  525.                 else begin
  526.                     c.h := 0;
  527.                     c.v := 0;
  528.                     index := 0;
  529.                     while LGetSelect(true, c, list) do begin
  530.                         c.v := c.v + 1;
  531.                         index := c.v;
  532.                     end;
  533.                     if index >= list^^.dataBounds.bottom then begin
  534.                         index := list^^.dataBounds.bottom - 1;
  535.                     end;
  536.                     SetSingleSelection(index);
  537.                 end;
  538.             end;
  539.             upArrowChar:  begin
  540.                 if last_event_had_command then begin
  541.                     OpenParent;
  542.                 end
  543.                 else begin
  544.                     c.h := 0;
  545.                     c.v := 0;
  546.                     if not LGetSelect(true, c, list) then begin
  547.                         c.v := list^^.dataBounds.bottom;
  548.                     end;
  549.                     if c.v > 0 then
  550.                         c.v := c.v - 1;
  551.                     SetSingleSelection(c.v);
  552.                 end;
  553.             end;
  554.             homeChar:  begin
  555.                 LScroll(0, -list^^.dataBounds.bottom, list);
  556.             end;
  557.             endChar:  begin
  558.                 LScroll(0, list^^.dataBounds.bottom, list);
  559.             end;
  560.             pageUpChar:  begin
  561.                 LScroll(0, -(list^^.visible.bottom - list^^.visible.top - 2), list);
  562.             end;
  563.             pageDownChar:  begin
  564.                 LScroll(0, (list^^.visible.bottom - list^^.visible.top - 2), list);
  565.             end;
  566.             tabChar:  begin
  567.                 if last_event_had_shift then begin
  568.                     if not GetFirstSelection(c) | not SelectFirstBefore(GetUniqueEntryName(c)) then begin
  569.                         dummy := SelectFirstBefore(chr(255));
  570.                     end;
  571.                 end
  572.                 else begin
  573.                     if not GetLastSelection(c) | not SelectFirstAfter(GetUniqueEntryName(c)) then begin
  574.                         dummy := SelectFirstAfter('');
  575.                     end;
  576.                 end;
  577.             end;
  578.             3, 13:  begin
  579.                 DoDoubleClick;
  580.             end;
  581.             otherwise begin
  582.                 if ch >= ' ' then begin
  583.                     if last_event_time - typed_time > 60 then begin
  584.                         typed_chars := '';
  585.                     end;
  586.                     typed_time := last_event_time;
  587.                     typed_chars := concat(typed_chars, ch);
  588.                     if not SelectFirstAfter(typed_chars) then begin
  589.                         dummy := SelectFirstBefore(chr(255));
  590.                     end;
  591.                 end;
  592.             end;
  593.         end;
  594. { WARNING: self may have been destroyed! }
  595.     end;
  596.  
  597.     procedure ListWindowObject.DoItemWhere (er: eventRecord; item: integer);
  598.         var
  599.             didit: boolean;
  600.             ctl: ControlHandle;
  601.             part, value: integer;
  602.             r: rect;
  603.             local: Point;
  604.     begin
  605.         case item of
  606.             list_item:  begin
  607.                 SetPort(window);
  608.                 local := er.where;
  609.                 GlobalToLocal(local);
  610.                 if local.v < header_height then begin
  611.                     GetDItemRect(window, list_item, r);
  612.                     r.bottom := r.top + header_height;
  613.                     DoHeaderClick(r, local, er.modifiers);
  614.                 end
  615.                 else begin
  616.                     didit := false;
  617.                     if hcontrol <> nil then begin
  618.                         part := FindControl(local, window, ctl);
  619.                         if ctl = hcontrol then begin
  620.                             didit := true;
  621.                             if part = inThumb then begin
  622.                                 value := GetCtlValue(hcontrol);
  623.                                 part := TrackControl(hcontrol, local, nil);
  624.                                 if part <> 0 then begin
  625.                                     list_offset := GetCtlValue(hcontrol);
  626.                                     if value <> list_offset then begin
  627.                                         InvalRect(window^.portRect);
  628.                                     end;
  629.                                 end;
  630.                             end
  631.                             else begin
  632.                                 action_listobj := self;
  633.                                 value := TrackControl(hcontrol, local, @HActionProc);
  634.                             end;
  635.  
  636.                         end;
  637.                     end;
  638.                     if not didit & DoLClick(er) then begin
  639.                         DoDoubleClick;
  640.                     end;
  641.                 end;
  642.             end;
  643.             otherwise
  644.                 inherited DoItemWhere(er, item);
  645.         end;
  646.     end;
  647.  
  648.     procedure ListWindowObject.DoActivateDeactivate (activate: boolean);
  649.     begin
  650.         LActivate(activate, list);
  651.         if hcontrol <> nil then begin
  652.             if activate then begin
  653.                 ShowControl(hcontrol);
  654.             end
  655.             else begin
  656.                 HideControl(hcontrol);
  657.             end;
  658.         end;
  659.         inherited DoActivateDeactivate(activate);
  660.     end;
  661.  
  662.     procedure ListWindowObject.Resize;
  663.         const
  664.             invis = 0;
  665.             vis = 255;
  666.         var
  667.             r: rect;
  668.             width, height, nheight, lineheight, lines: integer;
  669.     begin
  670.         SetPort(window);
  671.         lineheight := list^^.cellSize.v;
  672.         width := window^.portrect.right - window^.portrect.left;
  673.         height := window^.portrect.bottom - window^.portrect.top;
  674.         nheight := (height - header_height - 16) mod lineheight;
  675.         if nheight <> 0 then begin
  676.             SizeWindow(window, width, height - nheight, false);
  677.         end;
  678.         growRect.top := (50 + lineheight - 1) div lineheight * lineheight + header_height + 16;
  679.         r.left := 0;
  680.         r.right := window^.portrect.right + 1;
  681.         if r.right > max_display_width then
  682.             r.right := max_display_width;
  683.         r.top := 0;
  684.         r.bottom := window^.portrect.bottom;
  685.         SetDItemRect(window, list_item, r);
  686.         r.top := r.top + header_height + 1;
  687.         r.bottom := r.bottom - 15;
  688.         height := r.bottom - r.top;
  689.         list^^.rView.topleft := r.topleft; { LMove???? }
  690.         LSize(r.right - r.left - 16, height, list);
  691.         if hcontrol <> nil then begin
  692.             hcontrol^^.contrlVis := invis;
  693.             MoveControl(hcontrol, r.left, r.bottom);
  694.             SizeControl(hcontrol, r.right - r.left - 15, 16);
  695.             AdjustHContol(false);
  696.             hcontrol^^.contrlVis := vis;
  697.         end;
  698.         zoomSize.v := list^^.cellSize.v * (list^^.dataBounds.bottom + 1) + 4 + header_height + 1;
  699.         InvalRect(window^.portRect);
  700.         inherited Resize;
  701.     end;
  702.  
  703.     procedure ListWindowObject.DrawGrow;
  704.         var
  705.             r: rect;
  706.     begin
  707.         SetRect(r, -30000, header_height + 1, 30000, 30000);
  708.         DrawTheFriggingGrowIcon(window, r);
  709.     end;
  710.  
  711.     function ListWindowObject.CountSelections: integer;
  712.     begin
  713.         CountSelections := LCountSelections(list);
  714.     end;
  715.  
  716.     function ListWindowObject.IsSelection: boolean;
  717.     begin
  718.         IsSelection := LHasSelection(list);
  719.     end;
  720.  
  721.  
  722. end.